/*
 *
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */

package com.LibreGeoSocial.App.AR.Overlays;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.graphics.Paint.Align;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.LibreGeoSocial.App.R;

public class DrawResource extends View {
	
	public static final float MAX_AZIMUTH_VISIBLE = 30; 
	public static final float MAX_ELEVATION_VISIBLE = 20;
	private static final int MAX_ICON_SIZE = 48;
	private static final int MIN_ICON_SIZE = 24;
	private static final float CLICK_RANGE = 25;
//	private static final float CENTER_RANGE = 7;
	
	private float posx, posy;
	private String name;
	private float azimuth,elevation;
//	private float distance;
	private Bitmap bitmap_normal;
	private Bitmap bitmap_clicked;
	private Bitmap bitmap;
	private int icon_size;
	private boolean draw_arrow;
//	private boolean center = false;
	private float cx, cy;
	private long age = 0;
	
	private OnBoxChangeListener onBoxChangeListener;
	private OnIconClickListener onIconClickListener;
	
	public DrawResource(Context context, String name, Bitmap type) {
		super(context);
		// TODO Auto-generated constructor stub
		this.name = name;
		this.draw_arrow = false;
		icon_size = (int) MIN_ICON_SIZE;
		if(type != null){
			this.bitmap_clicked = Bitmap.createScaledBitmap(type, MAX_ICON_SIZE, MAX_ICON_SIZE, true);
		}else{
			this.bitmap_clicked = Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), 
					R.drawable.needle_white_16), MAX_ICON_SIZE, MAX_ICON_SIZE, true);
		}
		this.bitmap_normal = Bitmap.createScaledBitmap(bitmap_clicked, icon_size, icon_size, true);
		this.bitmap = this.bitmap_normal;
	}
//	
//	public void setCenter (boolean center){
//		this.center = center;
//	}
	
	public void setValues (float azimuth, float elevation, float distance){
		this.azimuth = azimuth;
		this.elevation = elevation;
//		this.distance = distance;
	}
	
	public void drawDistance(boolean draw){
		draw_arrow = draw;
	}
	
	@Override
	protected void onDraw(Canvas canvas){
		int w = canvas.getWidth();
        int h = canvas.getHeight();
        cx = ((float)w) / 2;
        cy = ((float)h) / 2 -12.5f;
        //float inclination;
        
        //inclination = elevation -CENTER_ELEVATION;
        if ((Math.abs(azimuth)>MAX_AZIMUTH_VISIBLE) || 
        		(Math.abs(elevation)>MAX_ELEVATION_VISIBLE))
        	return;
        
//        if(Math.abs(azimuth) < CENTER_RANGE)
//        	center = true;
        
        posx = cx + (float)(Math.sin(Math.toRadians(azimuth))/Math.sin(Math.toRadians(MAX_AZIMUTH_VISIBLE))) * cx;
        posy = cy + (float)(Math.sin(Math.toRadians(elevation))/Math.sin(Math.toRadians(MAX_ELEVATION_VISIBLE))) * cy;
        
        
		Paint paint = new Paint();
		paint.setARGB(250,255,255,255);
		paint.setAntiAlias(true);
		paint.setFakeBoldText(true);
		paint.setTextAlign(Align.CENTER);
		paint.setTypeface(Typeface.SANS_SERIF);
		paint.setTextSize(18);

//		Paint backPaint = new Paint();
//		backPaint.setARGB(175,0,0,0);
//		backPaint.setShader(new LinearGradient(posx, posy + (icon_size/2) + 5, 
//				posx, posy + (icon_size/2) + 30, Color.WHITE, Color.BLACK, TileMode.MIRROR));
//		backPaint.setAntiAlias(true);
//		backPaint.setStyle(Style.FILL);

		if(draw_arrow){
			icon_size = MAX_ICON_SIZE;
			bitmap = bitmap_clicked;
		}else{
			icon_size = MIN_ICON_SIZE;
			bitmap = bitmap_normal;
		}
		 
		Path arrow_path = new Path();
		arrow_path.moveTo(posx-10, posy + (icon_size/2) + 10);
		arrow_path.lineTo(posx, posy + (icon_size/2));
		arrow_path.lineTo(posx+10, posy + (icon_size/2) + 10);
		
		//canvas.drawOval(oval,paint);
		// Drawing icon
		canvas.drawBitmap(bitmap, posx - (icon_size/2), posy - (icon_size/2), null);
		
		// calculating box padding
		if(draw_arrow && (onBoxChangeListener != null)){
			int left = (int)Math.max(0, (posx - 75));
			int top = (int)(posy + (icon_size/2) + 10);
			int right = (int)Math.max(0, (w - (left + 150)));
			int bottom = (int)Math.max(0, (h - (top + 200)));
			
			canvas.drawPath(arrow_path, paint);
			onBoxChangeListener.onChange(left, top, right, bottom);
			
		}
		age = System.currentTimeMillis();
		super.onDraw(canvas);
	}
	 
	@Override
	public boolean onTouchEvent(MotionEvent event){

		Log.i(name, Integer.toString(event.getAction()));
		switch(event.getAction()){
		case MotionEvent.ACTION_DOWN:
			if((System.currentTimeMillis()-age) > 1000)
				break;
			
			float posx = this.posx;
			float posy = this.posy;

			float click_posx = event.getX();
			float click_posy = event.getY();

			if ((click_posx > (posx - CLICK_RANGE)) && (click_posy > (posy - CLICK_RANGE)) &&
					(click_posx < (posx + CLICK_RANGE)) && (click_posy < (posy + CLICK_RANGE))){

				draw_arrow = !draw_arrow;
				bringToFront();

				if(onIconClickListener != null)
					onIconClickListener.onClick(draw_arrow);

				return true;
			}
			break;
		}


		return false;
	}
	 
	public boolean forceClick(){
		if((System.currentTimeMillis()-age) > 1000)
			return false;
		bringToFront();

		draw_arrow = true;
		if(onIconClickListener != null)
			onIconClickListener.onClick(true);
		
		return true;
	}

	public void setOnBoxChangeListener(OnBoxChangeListener onBoxChangeListener){
		this.onBoxChangeListener = onBoxChangeListener;
	}

	public void unregisterBoxListener(){
		this.onBoxChangeListener = null;
		draw_arrow = false;
	}

	public void setOnIconClickListener(OnIconClickListener onIconClickListener){
		this.onIconClickListener = onIconClickListener;
	}

	public void unregisterIconClickListener(){
		this.onIconClickListener = null;
	}

	/* Interfaces */

	public interface OnBoxChangeListener {
		public abstract void onChange(int left, int top, int right, int bottom);
	}

	public interface OnIconClickListener {
		public abstract void onClick(boolean isOpen);
	}
}